/*-------------------------------------------------------------------------*/
/**
  @file		prototypes.h
  @author	Renaud Wanschoor
  @date	july 2004
  @version	$Revision: 2.13 $
  @brief	prototypes for plib functions

  note on heaps, the way i am using heaps is a bit special, in order
  to be able to use heaps, two elements are required:
  - a heap structure (of course doooh)
  - an array for additional information about heap element

  in order to retrive additional information when the head of the heap is
  retrieved the heap and the array must be consistent. In order not to break
  the consistency the following must be done
  - the first element of the array must be inserted first into the heap,
  the second in second and so on...
  - if your heap is built and you want to add an new element it must be
  inserted at the end of the array and the inserted into the heap
  - if you physically remove an element of the heap it must be physically
  removed from the array (replaced by the last element of the array)

  when a heap function return pos it is the position of additional information
  in the array. This method seems good has dll priority queues are extremely 
  fast and it avoids load of malloc and free but some mind gymnastic is
  required as mistakes are easy to do and hard to find (the only link between
  the array and the heap is in your mind)
  
*/
/*--------------------------------------------------------------------------*/

/***********************************************
 ***********************************************
 **                                           **
 **                utils.h                    **
 **                                           **
 ***********************************************
 ***********************************************/
/* error handling */
void U_error(int,char *,...);
int U_Warning(int ,char *,...);

/* memory allocation */
void** U_smalloc(int n, size_t b,char *msg);
void** U_ssmallocdouble(int nb,double ini,char *msg);
void** U_ssmallocint(int nb,int ini,char *msg);
void** U_srealloc(void *ptr,int n,size_t b,char *msg);
void** U_smallocxy(int x,int y,size_t d,char *msg);
void** U_sreallocxy(void *p,int old_x,int old_y,int new_x,int new_y,size_t size, char *msg);

void U_free(char *msg,...);

/* str stuff */
void U_filename(char *dest, char* url);

/* log file reading */
int U_readLine(FILE*);
void U_freeline(void);

/* serialize utils */
int U_serializeIntArray(int *array,int size, FILE* fp);
int* U_unserializeIntArray(int, FILE*,...);
int U_serializeStr(char *s,FILE* fp);
char* U_unserializeStr(FILE* fp);

/* quicksort */
void U_quickSort(T *a, tblIndex lb, tblIndex ub,T** l,int nb);

/* stat utils */
int U_intStat(int* s, int size,double* min, int* min_p,
	      double* max,int* max_p,
	      double* avg, double* stddev, double* sum);
int U_dbStat(double* s, int size,double* min, int* min_p,
	     double* max, int* max_p,
	     double* avg, double* stddev, double* sum);

/* debugging memory */
#ifdef DEBUG
void dbg_tag(int u_nb);
void dbg_alloc(void*, char*);
void dbg_realloc(void* p,void* new_p);
void dbg_free(void*, char*);
void dbg_printmem();
void dbg_freemem();
void dbg_isemptymem();
#endif

/***********************************************
 ***********************************************
 **                                           **
 **                md_io.h                    **
 **                                           **
 ***********************************************
 ***********************************************/
/****************/
/* command line */
/****************/
void IO_args(int argc, char *argv[],int *def, int *odef, int *a, char *opt, IoCtrl *c);
int IO_stat(int tool,void* graph,void *grid,
	     double *v_cutedge,double *v_tcc,
	     double *v_imbalance,double *v_met,double *v_met025,
	     double *v_met05,double *v_met1,double *v_met2,
	     int **v_proVW,double **v_proET);
int IO_statVol(int tool,void* graph,void* grid,double *v_met,double** v_proET);

/**********/
/* output */
/**********/
void IO_write(int tool,void* graph,void* grid,
	      char* F_output,int level,int id);
void IO_writeLog(int tool,void *graph, void *grid, int edgecut,
		 int ctype, int wtype, int rtype,
		 int cseed, int iseed, int rseed,
		 char* F_graph, char* F_grid,char* F_output,char *F_serialize,
		 int out_id,
		 float t_coa, float t_ini, float t_ref, float t_execbal, float t_tot);
void IO_writeBetLog(int tool,void *graph, void *grid, int edgecut,
		    int ctype, int wtype, int rtype,
		    int cseed, int iseed, int rseed,
		    char* F_graph, char* F_grid,char* F_output,char *F_serialize,
		    int out_id);
/***********************************************
 ***********************************************
 **                                           **
 **                pqueue.h                   **
 **                                           **
 ***********************************************
 ***********************************************/
/************************************************************************/
/************************************************************************/
/**                                                                    **/
/**       HeapFarm for memory allocation of Heaps and others           **/
/**                                                                    **/
/************************************************************************/
/************************************************************************/
void   MEM_Init(Mem*);
void   __MEM_Need(Mem*, size_t size);
void   __MEM_Needxy(Mem* f, int x, int y, size_t size);
void   MEM_Allocate(Mem*);
void*  __MEM_Request(Mem*,size_t size);
void*  __MEM_Requestxy(Mem* f,int x, int y, size_t size);
void   MEM_Free(Mem*);

/************************************************************************/
/************************************************************************/
/**                                                                    **/
/**                            Heap interface                          **/
/**                                                                    **/
/************************************************************************/
/************************************************************************/
/**
 * \brief Initialize the heap structure and acknowledge the farm of needed
 * memory
 *
 * input :
 *   - farm  : pointer to working farm structure
 *   - heap  : pointer to free heap structure
 *   - size  : maximum size of continuous heap
 */
void   HeapInit(Mem*, Heap*,int size);

/**
 * \brief Clean Heap (make it empty) keeping previously requested memory
 * can only work on continuous heap
 *
 * input :
 *   - heap  : pointer to working heap structure
 */
void   HeapClean(Heap* h);
/**
 * \brief Free Heap
 *
 * input :
 *   - heap  : pointer to working heap structure
 */
void   HeapFree(Heap* h);
/**
 * \brief Insert gain into heap and return position in heap
 *
 * input :
 *   - heap  : pointer to working heap structure
 *   - gain  : gain value
 *   - pos   : force insert in a given position (-1 otherwise)
 * output :
 *   integer to position in heap
 */
int    HeapInsert(Heap*, double gain);
/**
 * \brief physically remove an element from the heap (so another one can be
 * inserted
 *
 * input :
 *   - heap  : pointer to working heap structure
 *   - pos   : force insert in a given position (-1 otherwise)
 */
void   HeapRemove(Heap*, int pos);
/**
 * \brief Update a heap element in position pos with gain
 *
 * input :
 *   - heap  : pointer to working heap structure
 *   - pos   : position in heap
 */
void   HeapUpdate(Heap*, int pos, double gain);
/**
 * \brief See the gain of the head of the heap (maximum gain in heap)
 *
 * input :
 *   - heap  : pointer to working heap structure
 *
 * output :
 *   - gain value
 */
double HeapSeeHead(Heap*);
/**
 * \brief Return the position in the heap of the head
 *
 * input :
 *   - heap  : pointer to working heap structure
 *
 * output :
 *   integer to position in heap
 */
int    HeapGetHead(Heap*);
/**
 *
 * \brief Invert the gain of the head and replace it in the heap
 *
 * input :
 *   - heap  : pointer to working heap structure
 */
void   HeapUpdateHead(Heap*);
/**
 * \brief Remove the first element of the heap and return a pointer to this
 * element (the element is not physically removed)
 *
 * input :
 *   - heap  : pointer to working heap structure
 * output:
 *   position in heap of removed element
 */
int    HeapRemoveHead(Heap*);
/**
 * \brief Return the gain of an element
 *
 * input :
 *   - heap  : pointer to working heap structure
 *   - pos   : position in heap
 * output:
 *   - gain of the element
 */
double HeapGetGain(Heap* h,int pos);

/********************* FOR DEBUGGING */
//#ifdef DEBUG
int    HeapPos(Heap*,int idx);
double HeapGain(Heap*, int idx);
void   HeapPrint(Heap* h);
//#endif

/************************************************************************/
/************************************************************************/
/**                                                                    **/
/**                         plib_graph.c                               **/
/**                                                                    **/
/************************************************************************/
/************************************************************************/
PlotGraphType* PLIBG_Init(void);
void PLIBG_Allocate(PlotGraphType* g);
void PLIBG_Free(PlotGraphType *graph);
int PLIBG_ReadWhere(PlotGraphType *graph,char* F_output, int id);
int PLIBG_Copy(PlotGraphType* dest,PlotGraphType* src);
int PLIBG_SwitchWhere(PlotGraphType *g,int *where,int **old_where);
int PLIBG_Insert(PlotGraphType* current,PlotGraphType* new);
int PLIBG_DegreeStats(PlotGraphType *g,double *min,double *max,double *avg,double *stddev, double *sum);
int PLIBG_CutEdgeStats(PlotGraphType *g,double *min,double *max,double *avg,double *stddev, double* sum);
int PLIBG_WeightStats(PlotGraphType *g,double *min,double *max,double *avg,double *stddev, double *sum);
int PLIBG_EweightStats(PlotGraphType *g,double *min,double *max,double *avg,double *stddev, double *sum);
int* PLIBG_ReadIniWhere(PlotGraphType *graph,char* F_output,int id,int *ptr);
PlotGraphType* PLIBG_Read(FILE *fp);
PlotGraphType *PLIBG_Unserialize(int* tool,
				 char *F_ser,PlotGraphType *graph,
				 char **F_graph,char **F_grid,
				 int* level, 
				 int* CType, int* WType, int *RType,
				 int* CSeed, int *ISeed, int *RSeed);
PlotGraphType* PLIBG_Buildcoarse(int tool,PlotGraphType* graph);
void PLIBG_FreeMultiple(PlotGraphType* graph);
double* PLIBG_VtxsDegree(PlotGraphType *g,double *ptr);
double* PLIBG_VtxsWeight(PlotGraphType *g,double *ptr);
double* PLIBG_VtxsCutedge(PlotGraphType *g,double *ptr);
int* PLIBG_BuildWhere(PlotGraphType *cg,PlotGraphType *fg);
int* PLIBG_PartEdges(PlotGraphType *g,int vtx, int* ptr);
int PLIBG_NbProc(PlotGraphType *g);

/************************************************************************/
/************************************************************************/
/**                                                                    **/
/**                          plib_grid.c                               **/
/**                                                                    **/
/************************************************************************/
/************************************************************************/
void* PLIBN_Init(void);
void PLIBN_Free(PlotGridType *grid);
double PLIBN_RatioRef(PlotGridType *g,double ratio);
PlotGridType* PLIBN_Read(FILE* fp);
int PLIBN_Progen(PlotGraphType *graph, PlotGridType *grid);
int PLIBN_RefineStats(PlotGraphType *g, PlotGridType *grid,
		      double *cutedge,double *tcc,
		      double *imbalance,double *met,double *met025,
		      double *met05,double *met1,double *met2,
		      double *proVWmin,double *proVWmax,
		      double *proVWavg,double *proVWstddev,
		      double *proVWsum,double *exec,
		      double *proETmin,
		      double *proETmax,double *proETavg,
		      double *proETstddev,double *proETsum);
int PLIBN_Imbalance(PlotGraphType *g,double *imb,PlotGridType *grid);
int PLIBN_CutEdgeStats(PlotGraphType *g,
		  double *min,double *max,double *avg,double *stddev, 
		  double* sum,PlotGridType* grid);

/************************************************************************/
/************************************************************************/
/**                                                                    **/
/**                       plib_general.c                               **/
/**                                                                    **/
/************************************************************************/
/************************************************************************/
FILE* PLIB_SerializeInit(int tool, int count,
			 char *filename,int outresult, int id,
			 char* F_graph, char* F_grid,
			 int CType, int WType, int RType,
			 int CSeed, int ISeed, int RSeed);
FILE* PLIB_UnserializeInit(int* tool, char *F_ser,
			   char **F_graph,char **F_grid,
			   int* level, 
			   int* CType, int* WType, int *RType,
			   int* CSeed, int *ISeed, int *RSeed);

/************************************************************************/
/************************************************************************/
/**                                                                    **/
/**                            randnum.c                               **/
/**                                                                    **/
/************************************************************************/
/************************************************************************/
void ran_start(int seed);
void randnum(int range, int *a);
